package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.piggy.common.core.constant.SecurityConstants;
import com.piggy.common.core.domain.R;
import com.piggy.common.core.utils.FeignResultUtils;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.logi.sys.api.bo.LogiDeptLineEditBo;
import com.piggy.logi.sys.api.vo.LogiDeptLineExtVo;
import com.piggy.logi.sys.bo.LogiDeptLineQueryBo;
import com.piggy.logi.sys.domain.LogiDeptLine;
import com.piggy.logi.sys.mapper.LogiDeptLineMapper;
import com.piggy.logi.sys.service.ILogiDeptLineService;
import com.piggy.sys.api.RemoteDistrictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务商常用线路管理Service业务层处理
 *
 * @author piggy
 * @date 2023-12-04
 */
@Slf4j
@Service
public class LogiDeptLineServiceImpl extends ServiceImpl<LogiDeptLineMapper, LogiDeptLine> implements ILogiDeptLineService {

    @Resource
    private RemoteDistrictService districtService;

    @Override
    public LogiDeptLineExtVo queryById(Long id) {
        LogiDeptLineExtVo vo = getVoById(id, LogiDeptLineExtVo.class);
        if (ObjectUtil.isEmpty(vo)) {
            return vo;
        }
        return fillData(Lists.newArrayList(vo)).get(0);
    }

    @Override
    public TableDataInfo<LogiDeptLineExtVo> queryPageList(LogiDeptLineQueryBo bo) {
        PagePlus<LogiDeptLine, LogiDeptLineExtVo> result = pageVo(PageUtils.buildPagePlus(false), buildQueryWrapper(bo), LogiDeptLineExtVo.class);
        fillData(result.getRecordsVo());
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiDeptLineExtVo> queryList(LogiDeptLineQueryBo bo) {
        return fillData(listVo(buildQueryWrapper(bo), LogiDeptLineExtVo.class));
    }

    private LambdaQueryWrapper<LogiDeptLine> buildQueryWrapper(LogiDeptLineQueryBo bo) {
        LambdaQueryWrapper<LogiDeptLine> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, LogiDeptLine::getId, bo.getId());
        lqw.eq(bo.getMainDeptId() != null, LogiDeptLine::getMainDeptId, bo.getMainDeptId());
        lqw.eq(bo.getDepartDistrict() != null, LogiDeptLine::getDepartDistrict, bo.getDepartDistrict());
        lqw.eq(bo.getArriveDistrict() != null, LogiDeptLine::getArriveDistrict, bo.getArriveDistrict());
        lqw.in(CollUtil.isNotEmpty(bo.getDeptIdList()), LogiDeptLine::getMainDeptId, bo.getDeptIdList());
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogiDeptLineExtVo insertByAddBo(LogiDeptLineEditBo bo) {
        LogiDeptLine add = BeanUtil.toBean(bo, LogiDeptLine.class);
        save(add);
        return queryById(add.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogiDeptLineExtVo updateByEditBo(LogiDeptLineEditBo bo) {
        if (ObjectUtil.isEmpty(bo.getId())) {
            return insertByAddBo(bo);
        }
        LogiDeptLine update = BeanUtil.toBean(bo, LogiDeptLine.class);
        updateById(update);
        return queryById(update.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchByAddBo(List<LogiDeptLineEditBo> boList) {
        if (CollUtil.isEmpty(boList)) {
            return false;
        }

        boList.forEach(this::insertByAddBo);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchByUpdateBo(List<LogiDeptLineEditBo> boList, Long mainDeptId) {
        this.remove(Wrappers.<LogiDeptLine>lambdaQuery().eq(LogiDeptLine::getMainDeptId, mainDeptId));
        if (CollUtil.isEmpty(boList)) {
            return true;
        }

        boList.forEach(this::insertByAddBo);
        return true;
    }

    public List<LogiDeptLineExtVo> fillData(List<LogiDeptLineExtVo> extVos) {

        List<String> distIds = extVos.stream().map(vo -> {
            if(ObjectUtil.isNotNull(vo.getDepartDistrict()) && vo.getDepartDistrict() > 0){
                return vo.getDepartDistrict().toString();
            } else if (ObjectUtil.isNotNull(vo.getDepartCity()) && vo.getDepartCity() > 0) {
                return vo.getDepartCity().toString();
            } else {
                return vo.getDepartProvince().toString();
            }
        }).distinct().collect(Collectors.toList());
        distIds.addAll(extVos.stream().map(vo -> {
            if(ObjectUtil.isNotNull(vo.getArriveDistrict()) && vo.getArriveDistrict() > 0){
                return vo.getArriveDistrict().toString();
            } else if (ObjectUtil.isNotNull(vo.getArriveCity()) && vo.getArriveCity() > 0) {
                return vo.getArriveCity().toString();
            } else {
                return vo.getArriveProvince().toString();
            }
        }).distinct().collect(Collectors.toList()));
        distIds.add("-1");

        R<Map<String, String>> distMapR = districtService.getDistrictMap(distIds, SecurityConstants.INNER);
        FeignResultUtils.throwIfFailed(distMapR);
        Map<String, String> distMap = MapUtil.isNotEmpty(distMapR.getData()) ? distMapR.getData() : MapUtil.newHashMap();

        extVos.stream().peek(Any -> {
            if(ObjectUtil.isNotNull(Any.getArriveDistrict()) && Any.getArriveDistrict() > 0){
                Any.setArriveDistrictName(distMap.getOrDefault(Any.getArriveDistrict().toString(), ""));
            } else if (ObjectUtil.isNotNull(Any.getArriveCity()) && Any.getArriveCity() > 0) {
                Any.setArriveDistrictName(distMap.getOrDefault(Any.getArriveCity().toString(), ""));
            } else {
                Any.setArriveDistrictName(distMap.getOrDefault(Any.getArriveProvince().toString(), ""));
            }

            if(ObjectUtil.isNotNull(Any.getDepartDistrict()) && Any.getDepartDistrict() > 0){
                Any.setDepartDistrictName(distMap.getOrDefault(Any.getDepartDistrict().toString(), ""));
            } else if (ObjectUtil.isNotNull(Any.getDepartCity()) && Any.getDepartCity() > 0) {
                Any.setDepartDistrictName(distMap.getOrDefault(Any.getDepartCity().toString(), ""));
            } else {
                Any.setDepartDistrictName(distMap.getOrDefault(Any.getDepartProvince().toString(), ""));
            }
        }).collect(Collectors.toList());

        return extVos;
    }

}
